package com.myk.game.gobangchess.rooms;

import com.myk.game.gobangchess.Room;
import com.myk.game.gobangchess.constants.BoardStyleData;
import com.myk.game.gobangchess.constants.WinMode;
import com.myk.game.gobangchess.signs.AroundSign;
import com.myk.game.gobangchess.signs.GroundSign;
import com.myk.game.gobangchess.utils.GridsUtils;

import java.util.ArrayList;
import java.util.List;

/**
 * 墨棋
 * 代码修改自五子棋GoBangRoom，主要是加了canDropPiece函数
 */
public class InkGoBangRoom extends Room {

    public InkGoBangRoom(String roomName) {
        super(roomName, "苓舞设计的五子棋变种，通过加入了奇偶性相关的计算使其成为了非对称博弈棋，\n此版本是由Sigmoid改良后的高平衡性的版本。","墨棋", BoardStyleData.getGoBangStyle(19,19), true, true);
    }

    @Override
    public String getRuleText() {
        return "《墨棋》v0.5棋规：\n" +
                "轮流落子，除第一回合外，双方有不同的落子限制；\n" +
                "只要一条有棋子的线满足条件，就可以在那条线上的任意一格落子。\n" +
                "黑方：白子总数非奇数\n" +
                "白方：白子总数为奇数\n" +
                "\n" +
                "获胜条件：\n" +
                "1.直线连六\n" +
                "2.斜线连五";
    }

    @Override
    public void doRule(int row, int col, int value) {
        if (canDropPiece(row,col,value)){
            signList.clear();
            List<Integer> ids = new ArrayList<>();
            ids.add(getIndex(row,col));
            signList.add(new AroundSign(ids,"#00000000","#6600FF00",1.2f));
            curGrids[row][col] = value; //实际落子
            stepAdd(); //步数统计加增加

            //黑方落子时
            if (value == 1) {
                if (checkFormation(1) > 0) {//黑方连珠成功
                    doOver(WinMode.BLACK_WIN,player_black.getNickNameOrTemp() + "执黑棋战胜" + player_white.getNickNameOrTemp());
                }
                else {
                    int blankNum = GridsUtils.getDataCount(curGrids, 0);
                    if (blankNum == 0) {//没有胜负也没有空子了算战平
                        doOver(WinMode.BOTH_DRAW,player_black.getNickNameOrTemp() + "-黑棋战平" + player_white.getNickNameOrTemp() + "-白棋");
                    }
                    else {
                        int canDropSquareCount=0;
                        for(int i=0;i<19;i++) //绘制对方可落子的区域
                            for(int j=0;j<19;j++)
                                if(canDropPiece(i,j,2)){
                                    canDropSquareCount++;
                                    signList.add(new GroundSign(getIndex(i, j), "#667F4FFF", "#007F4FFF", 1.5f));
                                }
                        if(canDropSquareCount==0) //对手无处可去就赢了
                            doOver(WinMode.BLACK_WIN,player_black.getNickNameOrTemp() + "执黑棋战胜" + player_white.getNickNameOrTemp());
                        noticeWhiteMove();
                    }
                }
            }

            //白方落子时
            else if (value == 2) {
                if (checkFormation(2) > 0) {
                    doOver(WinMode.WHITE_WIN,player_white.getNickNameOrTemp() + "执白棋战胜" + player_black.getNickNameOrTemp());
                }
                else {
                    int blankNum = GridsUtils.getDataCount(curGrids, 0);  //没有胜负也没有空子了算战平
                    if (blankNum == 0) {
                        doOver(WinMode.BOTH_DRAW,player_black.getNickNameOrTemp() + "-黑棋战平" + player_white.getNickNameOrTemp() + "-白棋");
                    }
                    else {
                        int canDropSquareCount=0;
                        for(int i=0;i<19;i++) //绘制对方可落子的区域
                            for(int j=0;j<19;j++)
                                if(canDropPiece(i,j,1)){
                                    canDropSquareCount++;
                                    signList.add(new GroundSign(getIndex(i, j), "#667F4FFF", "#007F4FFF", 1.5f));
                                }
                        if(canDropSquareCount==0) //对手无处可去就赢了
                            doOver(WinMode.WHITE_WIN,player_white.getNickNameOrTemp() + "执白棋战胜" + player_black.getNickNameOrTemp());
                        noticeBlackMove();
                    }
                }
            }

        }
    }

    private final int[] dirX={-1,-1,0,1}, dirY={0,1,1,1};
    private boolean canDropPiece(int row,int col,int value){
        if(curGrids[row][col]!=0) return false;
        if(step<2) return true; //第一回合不需要判断
        //吐槽：为啥步数计数器是从0开始的啊...
        int x,y,sum;
        boolean flag=false;
        for(int i=0;i<4;i++){
            if(flag) break;
            sum=0;
            x=row+dirX[i]; y=col+dirY[i];
            while(x>-1 && x<19 && y>-1 && y<19){
                sum+=((curGrids[x][y]!=0)?(3-curGrids[x][y]):0);
                x+=dirX[i]; y+=dirY[i];
            }
            x=row-dirX[i]; y=col-dirY[i];
            while(x>-1 && x<19 && y>-1 && y<19){
                sum+=((curGrids[x][y]!=0)?(3-curGrids[x][y]):0);
                x-=dirX[i]; y-=dirY[i];
            }
            if(value==1){
                if(sum>0 && sum%2==0) flag=true;
            }else{
                if(sum%2==1) flag=true;
            }
        }
        return flag;
    }

    //获取成5的次数
    private int checkFormation(int value) {
        int rows = curGrids.length;
        int cols = curGrids[0].length;
        int formationCount = 0;

        // 水平方向
        for (int i = 0; i < rows; i++) {
            for (int j = 0; j < cols - 5; j++) {
                int length = 0;
                for (int k = j; k < j + 6; k++) {
                    if (curGrids[i][k] == value) {
                        length++;
                    }
                    else {
                        break;
                    }
                }
                if (length >= 6) { //需要六连，下同
                    formationCount += (length - 5);
                }
            }
        }

        // 垂直方向
        for (int i = 0; i < rows - 5; i++) {
            for (int j = 0; j < cols; j++) {
                int length = 0;
                for (int k = i; k < i + 6; k++) {
                    if (curGrids[k][j] == value) {
                        length++;
                    }
                    else {
                        break;
                    }
                }
                if (length >= 6) {
                    formationCount += (length - 5);
                }
            }
        }

        // 左上到右下方向
        for (int i = 0; i < rows - 4; i++) {
            for (int j = 0; j < cols - 4; j++) {
                int length = 0;
                for (int k = 0; k < 5; k++) {
                    if (curGrids[i + k][j + k] == value) {
                        length++;
                    }
                    else {
                        break;
                    }
                }
                if (length >= 5) {
                    formationCount += (length - 4);
                }
            }
        }

        // 右上到左下方向
        for (int i = 0; i < rows - 4; i++) {
            for (int j = 4; j < cols; j++) {
                int length = 0;
                for (int k = 0; k < 5; k++) {
                    if (curGrids[i + k][j - k] == value) {
                        length++;
                    }
                    else {
                        break;
                    }
                }
                if (length >= 5) {
                    formationCount += (length - 4);
                }
            }
        }

        return formationCount;
    }
}
